package com.hxz.graduationdesign;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class BilibiliUpVideoCrawler {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\chromedriver-win64\\chromedriver.exe");

        ChromeOptions options = new ChromeOptions();
        options.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36");
        // 无头模式
        options.addArguments("--headless");

        WebDriver driver = new ChromeDriver(options);

        try {

            int sum = 0;

            String upHomeUrl = "https://space.bilibili.com/38053181/video";
            driver.get(upHomeUrl);

            WebDriverWait wait = new WebDriverWait(driver, 30);

            // 等待视频列表加载
            wait.until(ExpectedConditions.presenceOfElementLocated(
                    By.cssSelector("li.small-item.fakeDanmu-item")
            ));

            // 滚动加载更多视频
            scrollToBottom(driver);

            // 提取视频信息
            List<WebElement> videos = driver.findElements(
                    By.cssSelector("li.small-item.fakeDanmu-item")
            );

            for (WebElement video : videos) {
                String title = video.findElement(By.cssSelector("a.title")).getText();
                String url = video.findElement(By.cssSelector("a.cover")).getAttribute("href");
                String playCount = video.findElement(By.cssSelector("span.play span")).getText();
                String uploadDate = video.findElement(By.cssSelector("span.time")).getText().trim();
                String duration = video.findElement(By.cssSelector("span.length")).getText();
                String danmuCount = "";

                try {
                    danmuCount = video.findElement(By.cssSelector("div.bili-cover-card__stats span:nth-child(2)")).getText();
                } catch (NoSuchElementException e) {
                    danmuCount = "N/A"; // 如果找不到弹幕数量元素，设置为"N/A"
                }
                sum++;
                System.out.println("标题: " + title);
                System.out.println("链接: " + url);
                System.out.println("播放量: " + playCount);
                System.out.println("时长: " + duration);
                System.out.println("发布日期: " + uploadDate);
                System.out.println("弹幕数量: " + danmuCount);
                System.out.println("----------------------");
            }

// 翻页继续爬取视频数据
            while (true) {
                WebElement nextPageButton = driver.findElement(By.cssSelector("li.be-pager-next"));
                if (nextPageButton.getAttribute("class").contains("be-pager-disabled")) {
                    break;
                }
                nextPageButton.click();
                wait.until(ExpectedConditions.presenceOfElementLocated(
                        By.cssSelector("li.small-item.fakeDanmu-item")
                ));
                scrollToBottom(driver);
                videos = driver.findElements(By.cssSelector("li.small-item.fakeDanmu-item"));
                for (WebElement video : videos) {
                    String title = video.findElement(By.cssSelector("a.title")).getText();
                    String url = video.findElement(By.cssSelector("a.cover")).getAttribute("href");
                    // 播放量
                    String playCount = video.findElement(By.cssSelector("span.play span")).getText();
                    String uploadDate = video.findElement(By.cssSelector("span.time")).getText().trim();
                    // 时长
                    String duration = video.findElement(By.cssSelector("span.length")).getText();
                    String danmuCount = "";

                    try {
                        danmuCount = video.findElement(By.cssSelector("div.bili-cover-card__stats span:nth-child(2)")).getText();
                    } catch (NoSuchElementException e) {
                        danmuCount = "N/A"; // 如果找不到弹幕数量元素，设置为"N/A"
                    }
                    sum++;
                    System.out.println("标题: " + title);
                    System.out.println("链接: " + url);
                    System.out.println("播放量: " + playCount);
                    System.out.println("时长: " + duration);
                    System.out.println("发布日期: " + uploadDate);
                    System.out.println("弹幕数量: " + danmuCount);
                    System.out.println("----------------------");
                }
            }

            System.out.println(sum);

        } catch (Exception e) {
            System.err.println("抓取失败，当前页面源码已保存到 error.html");
            savePageSource(driver, "error.html");
            e.printStackTrace();
        } finally {
            driver.quit();
        }
    }

    // 滚动到页面底部（触发懒加载）
    private static void scrollToBottom(WebDriver driver) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        long lastHeight = (long) js.executeScript("return document.body.scrollHeight");

        while (true) {
            js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
            try {
                Thread.sleep(2000); // 等待加载
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long newHeight = (long) js.executeScript("return document.body.scrollHeight");
            if (newHeight == lastHeight) break;
            lastHeight = newHeight;
        }
    }

    // 保存页面源码（用于调试）
    private static void savePageSource(WebDriver driver, String filename) {
        try {
            Files.write(Paths.get(filename), driver.getPageSource().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
